package xin.nick.rpc.provider.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import xin.nick.rpc.provider.handler.RpcServerHandler;

import java.util.Objects;

/**
 * @author Nick
 * @date 2021/7/4
 * @description
 */
@Slf4j
@Service
public class RpcServer implements DisposableBean {

    private NioEventLoopGroup bossGroup;

    private NioEventLoopGroup workerGroup;

    @Autowired
    RpcServerHandler rpcServerHandler;


    @Override
    public void destroy() throws Exception {
        if (Objects.nonNull(bossGroup)) {
            bossGroup.shutdownGracefully();
        }

        if (Objects.nonNull(workerGroup)) {
            workerGroup.shutdownGracefully();
        }
    }

    public void startServer(String ip, int port) {

       try {
           // 创建线程组
           bossGroup = new NioEventLoopGroup(1);
           workerGroup = new NioEventLoopGroup();

           // 创建服务端启动助手
           ServerBootstrap serverBootstrap = new ServerBootstrap();

           // 设置参数
           serverBootstrap.group(bossGroup, workerGroup)
                   .channel(NioServerSocketChannel.class)
                   .childHandler(new ChannelInitializer<SocketChannel>() {
                       @Override
                       protected void initChannel(SocketChannel socketChannel) throws Exception {
                           ChannelPipeline pipeline = socketChannel.pipeline();

                           // 添加String编解码器
                           pipeline.addLast(new StringDecoder());
                           pipeline.addLast(new StringEncoder());

                           // 业务处理
                           pipeline.addLast(rpcServerHandler);
                       }
                   });

           // 绑定端口
           ChannelFuture sync = serverBootstrap.bind(ip, port).sync();
           log.info("------------> 服务端启动成功: {} : {}", ip, port);
           sync.channel().closeFuture().sync();

       } catch(Exception e) {
            e.printStackTrace();
       }

    }
}
